From: Keir Fraser Date: Wed, 1 Jul 2009 13:58:31 +0000 (+0100) Subject: x86 hvm: Fix #UD interception. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~13665 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=70116ff26048b92a3a2e808806a79d6fb44505aa;p=xen.git x86 hvm: Fix #UD interception. * Interception should be standard part of HVM_TRAP_MASK * Failed intercept should quietly forward #UD to the guest Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index aae51c0e05..be78c65555 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1226,24 +1226,16 @@ static void svm_vmexit_ud_intercept(struct cpu_user_regs *regs) switch ( rc ) { case X86EMUL_UNHANDLEABLE: - gdprintk(XENLOG_WARNING, - "instruction emulation failed @ %04x:%lx: " - "%02x %02x %02x %02x %02x %02x\n", - hvmemul_get_seg_reg(x86_seg_cs, &ctxt)->sel, - ctxt.insn_buf_eip, - ctxt.insn_buf[0], ctxt.insn_buf[1], - ctxt.insn_buf[2], ctxt.insn_buf[3], - ctxt.insn_buf[4], ctxt.insn_buf[5]); - return; + svm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); + break; case X86EMUL_EXCEPTION: if ( ctxt.exn_pending ) hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0); - break; + /* fall through */ default: + hvm_emulate_writeback(&ctxt); break; } - - hvm_emulate_writeback(&ctxt); } static void wbinvd_ipi(void *info) diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c index d1b00093b8..d83fdc185a 100644 --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -227,8 +227,7 @@ static int construct_vmcb(struct vcpu *v) vmcb->exception_intercepts = HVM_TRAP_MASK - | (1U << TRAP_no_device) - | (1U << TRAP_invalid_op); + | (1U << TRAP_no_device); if ( paging_mode_hap(v->domain) ) { diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 881a9a832b..cd6e44073d 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -679,8 +679,7 @@ static int construct_vmcs(struct vcpu *v) __vmwrite(EXCEPTION_BITMAP, HVM_TRAP_MASK | (paging_mode_hap(d) ? 0 : (1U << TRAP_page_fault)) - | (1U << TRAP_no_device) - | (1U << TRAP_invalid_op)); + | (1U << TRAP_no_device)); v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_PE | X86_CR0_ET; hvm_update_guest_cr(v, 0); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index b5a74965ad..fdfcb8d2e6 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2258,34 +2258,26 @@ asmlinkage void vmx_enter_realmode(struct cpu_user_regs *regs) static void vmx_vmexit_ud_intercept(struct cpu_user_regs *regs) { - struct hvm_emulate_ctxt ctxt; - int rc; - - hvm_emulate_prepare(&ctxt, regs); - - rc = hvm_emulate_one(&ctxt); - - switch ( rc ) - { - case X86EMUL_UNHANDLEABLE: - gdprintk(XENLOG_WARNING, - "instruction emulation failed @ %04x:%lx: " - "%02x %02x %02x %02x %02x %02x\n", - hvmemul_get_seg_reg(x86_seg_cs, &ctxt)->sel, - ctxt.insn_buf_eip, - ctxt.insn_buf[0], ctxt.insn_buf[1], - ctxt.insn_buf[2], ctxt.insn_buf[3], - ctxt.insn_buf[4], ctxt.insn_buf[5]); - return; - case X86EMUL_EXCEPTION: - if ( ctxt.exn_pending ) - hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0); - break; - default: - break; - } - - hvm_emulate_writeback(&ctxt); + struct hvm_emulate_ctxt ctxt; + int rc; + + hvm_emulate_prepare(&ctxt, regs); + + rc = hvm_emulate_one(&ctxt); + + switch ( rc ) + { + case X86EMUL_UNHANDLEABLE: + vmx_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); + break; + case X86EMUL_EXCEPTION: + if ( ctxt.exn_pending ) + hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0); + /* fall through */ + default: + hvm_emulate_writeback(&ctxt); + break; + } } asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 4557cd0dcd..1a905272b0 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -268,7 +268,7 @@ static inline int hvm_do_pmu_interrupt(struct cpu_user_regs *regs) X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT))) /* These exceptions must always be intercepted. */ -#define HVM_TRAP_MASK (1U << TRAP_machine_check) +#define HVM_TRAP_MASK ((1U << TRAP_machine_check) | (1U << TRAP_invalid_op)) /* * x86 event types. This enumeration is valid for: